﻿namespace BM.Tools.WebControls.MForm.Design.PropertiesGeneration
{
    using System.Diagnostics.CodeAnalysis;

    using BM.Tools.WebControls.MForm.Controls;
    using EnvDTE;
    using EnvDTE80;

    /// <summary>
    /// This class is used to generate a single property from the provided property definition inside a provided code class.
    /// </summary>    
    internal class PropertyGenerator
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="PropertyGenerator"/> class.
        /// </summary>
        /// <param name="root">
        /// The MForm root control.
        /// </param>
        /// <param name="codeClass">
        /// The code class.
        /// </param>
        /// <param name="definition">
        /// The definition.
        /// </param>
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This code is invoked internally by the designer")]
        internal PropertyGenerator(Root root, CodeClass2 codeClass, PropertyDefinition definition)
        {
            Root = root;
            CodeClass = codeClass;
            Definition = definition;
        }

        /// <summary>
        /// Gets the MForm Root control.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This code is invoked internally by the designer")]
        internal Root Root
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the CodeClass in which the property will be generated.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This code is invoked internally by the designer")]
        internal CodeClass2 CodeClass
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the definition from which the property will be generated.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This code is invoked internally by the designer")]
        internal PropertyDefinition Definition
        {
            get;
            private set;
        }

        /// <summary>
        /// Performs the generation.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This code is invoked internally by the designer")]
        public void Generate()
        {
            var property = CodeClass.AddProperty(Definition.Name, null, Definition.ObjectType.FullName, -1, vsCMAccess.vsCMAccessPublic, null);            
            property.DocComment = GetDocComment();
            var editPoint = (EditPoint2)property.Getter.GetStartPoint(vsCMPart.vsCMPartBody).CreateEditPoint();

            editPoint.Delete(property.Getter.GetEndPoint(vsCMPart.vsCMPartBody));
            editPoint.Indent(null, 0);
            editPoint.Insert(GetReturnStatement());
            editPoint.InsertNewLine(1);
            editPoint.Indent(null, 3);
        }

        private string GetDocComment()
        {
            return string.Concat("<doc><summary>\nGets the item that can be found using the '", Definition.Path, "' path.\n</summary></doc>");
        }

        private string GetReturnStatement()
        {
            return string.Concat("return ", Root.ID, ".SelectSingle(\"", Definition.Path, "\") as ", Definition.ObjectType.FullName, ";");
        }
    }
}
